package com.red.star.macalline.data.utils;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.red.star.macalline.data.core.base.RedisRunner;
import com.red.star.macalline.data.core.constant.Constant;
import com.red.star.macalline.data.core.constant.RedisConstant;
import com.red.star.macalline.data.entity.SysParam;
import com.red.star.macalline.data.mappers.TemplateLogMapper;
import org.apache.http.client.fluent.Request;
import org.springframework.util.Assert;

import javax.annotation.Resource;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @author AMGuo
 * @Description
 * @date 2018/03/01 11:04
 */
public class WeiXinUtil {

    private static final String URL_PREFIX = "https://api.weixin.qq.com";

    private static final String CODE_URL_PREFIX = "https://mp.weixin.qq.com";

    private static final String APPID = "wx38defc1096ce180d";

    private static final String APPSECRET = "9e89a159d9babee2727591da98043d09";

    //获取access_token
    public static String ACCESS_TOKEN_URL = String.format(
            "%s/cgi-bin/token?grant_type=client_credential&appid=%s&secret=%s", URL_PREFIX, APPID, APPSECRET
    );

    //获取ticket
    public static String TICKET_URL = String.format(
            "%s/cgi-bin/qrcode/create?access_token=%s", URL_PREFIX, "%s"
    );

    //获取二维码链接
    public static String CODE_URL = String.format("%s/cgi-bin/showqrcode?ticket=%s", CODE_URL_PREFIX, "%s");

    //获取小程序二维码链接
    public static String WX_CODE_URL = String.format("%s/wxa/getwxacodeunlimit?access_token=%s", URL_PREFIX, "%s");

    //小程序模板信息接口
    public static String WX_MESSAGE_URL = String.format("%s/cgi-bin/message/wxopen/template/send?access_token=%s",
            URL_PREFIX, "%s");

    @Resource
    static TemplateLogMapper templateLogMapper;

    /**
     * 获取ticket
     *
     * @param redisRunner
     * @return
     */
    public static String fecthTicket(RedisRunner redisRunner) throws IOException {
        String ticket = redisRunner.cacheGet(RedisConstant.REDIS_DB_USER_SESSION, RedisConstant.TICKET);
        if (CheckUtil.isEmpty(ticket)) {
            String accessToken = fetchAccessToken(redisRunner);
            String url = String.format(TICKET_URL, accessToken);
            Request request = Request.Get(url);
            String body = HttpUtil.fetch(request);
            JSONObject jsonObject = JSON.parseObject(body);
            ticket = jsonObject.getString("ticket");
            redisRunner.cacheAddUpdate(RedisConstant.REDIS_DB_USER_SESSION, RedisConstant.TICKET, ticket, RedisConstant.TOKEN_EXPIRY);
        }
        return ticket;
    }

    /**
     * 获取Access Token
     *
     * @param redisRunner
     * @return
     */
    public static String fetchAccessToken(RedisRunner redisRunner) throws IOException {
        return TicketUtil.getAccessToken();
    }

    /**
     * 获取二维码url
     *
     * @param redisRunner
     * @return
     */
    public static String fecthCodeUrl(RedisRunner redisRunner) throws IOException {
        String ticket = fecthTicket(redisRunner);
        String codeUrl = String.format(CODE_URL, ticket);
        return codeUrl;
    }

    /**
     * 获取小程序二维码url
     *
     * @param redisRunner
     * @return 小程序二维码url
     * @throws UnsupportedEncodingException
     */
    public static String fecthWXCodeUrl(RedisRunner redisRunner) throws IOException {
        String accessToken = fetchAccessToken(redisRunner);
        String wxCodeUrl = String.format(WX_CODE_URL, accessToken);
        return wxCodeUrl;
    }

    public static String fecthWXCodeUrl() throws IOException {
        String accessToken = TicketUtil.getAccessToken();
        String wxCodeUrl = String.format(WX_CODE_URL, accessToken);
        return wxCodeUrl;
    }

    /**
     * 获取小程序模板信息url
     *
     * @param redisRunner
     * @return 小程序模板信息url
     */
    public static String fecthWXMessageUrl(RedisRunner redisRunner) throws IOException {
        String accessToken = fetchAccessToken(redisRunner);
        String wxMessageUrl = String.format(WX_MESSAGE_URL, accessToken);
        return wxMessageUrl;
    }

    /**
     * 获取小程序模板信息url
     *
     * @return 小程序模板信息url
     */
    public static String fecthWXMessageUrlNew() throws IOException {
        String accessToken = TicketUtil.getAccessToken();
        String wxMessageUrl = String.format(WX_MESSAGE_URL, accessToken);
        return wxMessageUrl;
    }

    /**
     * 发送小程序模板信息
     *
     * @param openId
     * @param formId
     * @param data            模板消息内容
     * @param emphasisKeyword 需要放大的字段
     * @param page            模板消息链接
     * @return
     * @throws IOException
     */
    public static Map fecthWXMessage(String openId, String formId, Map data, String emphasisKeyword, String page) throws IOException {
        return sendTemplateMsg(SysParam.WX_TEMP_POSTER_CARD_ID, openId, formId, data, emphasisKeyword, page);
    }

    /**
     * 发送模版消息
     *
     * @param templateId      模板消息ID
     * @param openId          接收者（用户）的 openid
     * @param formId          表单提交场景下，为 submit 事件带上的 formId；支付场景下，为本次支付的 prepay_id
     * @param data            模板内容，不填则下发空模板
     * @param emphasisKeyword 模板需要放大的关键词，不填则默认无放大
     * @param page            小程序页面（点击模板消息跳转）
     * @return 发送模版消息结果数据集
     * @throws IOException
     */
    public static Map sendTemplateMsg(String templateId, String openId, String formId, Map data, String emphasisKeyword, String page) throws IOException {
        Assert.notNull(templateId, "null of templateId");
        Assert.notNull(openId, "null of openId");
        Assert.notNull(formId, "null of formId");
        Assert.notNull(data, "null of data");
        Map templateMsg = new HashMap();
        //发送给
        templateMsg.put(Constant.TEMPLATE_POST_TOUSER, openId);
        //template_id
        templateMsg.put(Constant.TEMPLATE_POST_TEMPLATE_ID, templateId);
        //page
        templateMsg.put(Constant.TEMPLATE_POST_PAGE, page);
        //form_id
        templateMsg.put(Constant.TEMPLATE_POST_FORM_ID, formId);
        //data
        templateMsg.put(Constant.TEMPLATE_POST_DATA, data);
        templateMsg.put(Constant.TEMPLATE_POST_EMPHASIS, emphasisKeyword);
        String WXMessageUrl = WeiXinUtil.fecthWXMessageUrlNew();
        Request request = Request.Post(WXMessageUrl);
        String body = HttpUtil.fetch(request, JSONObject.toJSONString(templateMsg));
        Map result = new HashMap();
        result.put("body", body);
        if (!CheckUtil.isEmpty(body)) {
            JSONObject jsonObject = JSONObject.parseObject(body);
            if (!CheckUtil.isEmpty(jsonObject) && Integer.valueOf(0).equals(jsonObject.getInteger("errcode"))) {
                //将formId标记过期
                TicketUtil.changeStatus(openId, formId);
                result.put("flag", true);
                return result;
            }
        }
        result.put("flag", false);
        return result;
    }

    /**
     * 生成小程序二维码方法
     *
     * @param path 扫码跳转地址
     * @param map  scene
     * @return 图片base64  需在最前面加上  data:image/jpeg;base64,
     * @throws IOException
     */
    public static String backWXCodeImageBase64(String path, Map<String, String> map) throws IOException {
        Map<String, String> param = new HashMap<String, String>();
        String scene = "";
        for (Map.Entry entry : map.entrySet()) {
            if (!CheckUtil.isEmpty(entry)) {
                scene += entry.getKey() + "=" + entry.getValue() + "&";
            }
        }
        if (!CheckUtil.isEmpty(scene) && "&".equals(scene.substring(scene.length() - 1, scene.length()))) {
            scene = scene.substring(0, scene.length() - 1);
        }
        param.put("scene", scene);
        param.put("page", path);
        Request request = Request.Post(WeiXinUtil.fecthWXCodeUrl());
        return Base64.getEncoder().encodeToString(HttpUtil.fetchByte(request, JSONObject.toJSONString(param)));
    }

    public static void main(String[] args) throws IOException {
//		Map<String, String> map = new HashMap<String, String>();
//		map.put("cardName", "11");
//		String result = backWXCodeImageBase64(WX_BAOBIAO_PAGE, map);
//		System.err.println(result);
//		Map data, Integer adminId, Integer templateId, String source
//		String openId, String formId, Map data
//		内容1
        Map data = new HashMap();
        Map keyword1 = new HashMap();
        keyword1.put(Constant.TEMPLATE_POST_DATA_VALUE, "预约内容");
        keyword1.put(Constant.TEMPLATE_POST_DATA_COLOR, "#173177");
        Map keyword2 = new HashMap();
        keyword2.put(Constant.TEMPLATE_POST_DATA_VALUE, "预约内容");
        keyword2.put(Constant.TEMPLATE_POST_DATA_COLOR, "#173177");
        Map keyword3 = new HashMap();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日");
        keyword3.put(Constant.TEMPLATE_POST_DATA_VALUE, sdf.format(new Date()));
        keyword3.put(Constant.TEMPLATE_POST_DATA_COLOR, "#173177");
        data.put(Constant.TEMPLATE_POST_DATA_1, keyword1);
        //内容2
        data.put(Constant.TEMPLATE_POST_DATA_2, keyword2);
        //内容3
        data.put(Constant.TEMPLATE_POST_DATA_3, keyword3);
        String page = SysParam.WX_TEMP_PAGE_POSTER_CARD + "?dataType=7&dataId=" + 6;
        System.err.println(fecthWXMessage("oN6T10Osa8jWCgUlSYwqaa_44vUs",
                "1522205337831", data, Constant.TEMPLATE_POST_EMPHASIS_VALUE, page));
    }


}
